/*
 * Copyright (c) 2001, 2002 Boris Pruessmann and others. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Common Public License v0.5 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/cpl-v05.html
 * 
 * Contributors: Boris Pruessmann - Initial implementation. David Corbin - added
 * method to parse depot path into individual elements
 */
package net.sourceforge.perforce.core.resources;

import com.google.common.collect.Lists;

import java.io.InputStream;
import java.text.ParseException;
import java.util.List;

import net.sourceforge.perforce.core.PerforceException;
import net.sourceforge.perforce.core.api.IPerforceServer;
import net.sourceforge.perforce.core.syncinfo.ResourceSyncInfo;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.PlatformObject;

/**
 * @version $Revision: 488 $
 * @author <a href="mailto:bpruessmann@users.sourceforge.net">Boris
 *         Pruessmann</a>
 * @author <a href="mailto:dcorbin@users.sourceforge.net">David Corbin</a>
 */
public abstract class RemoteResource extends PlatformObject {
  //----------------------------------------------------------------------------
  // - Private Methods

  /** Stores the Perforce Server. */
  private IPerforceServer server;
  /** Stores the parent. */
  private RemoteFolder parent;

  // -----------------------------------------------------------------------
  // Public Static Methods

  /**
   * Splits a repository path into its parts.
   * 
   * @param path he repository path.
   * @return list containing the parts.
   * 
   * @throws ParseException in case of an error
   */
  public static List<String> splitRepositoryPath(String path) throws ParseException {
    // TODO(rcleveng): This isn't used, maybe it's caller is just commented out?
    List<String> list = Lists.newLinkedList();
    if (!path.startsWith("//")) {
      throw new ParseException("not a well-formed depot path", 0);
    }

    path = path.substring(2);
    if (path.startsWith("/")) {
      throw new ParseException("not a well-formed depot path", 2);
    }

    while (path.length() > 0) {
      int slashPosition = path.indexOf('/');
      if (slashPosition < 0) {
        list.add(path);
        return list;
      }

      String fileName = path.substring(0, slashPosition);
      path = path.substring(slashPosition + 1);
      list.add(fileName);
    }
    list.add("");
    return list;
  }

  //----------------------------------------------------------------------------
  // -- Public Methods

  /**
   * Gets the parent.
   * 
   * @return Returns a RemoteFolder
   */
  public RemoteFolder getParent() {
    return parent;
  }

  /**
   * Sets the parent.
   * 
   * @param parent The parent to set
   */
  public void setParent(RemoteFolder parent) {
    this.parent = parent;
  }

  /**
   * Returns the server.
   * 
   * @return IPerforceServer
   */
  public IPerforceServer getServer() {
    return server;
  }

  /**
   * Sets the server.
   * 
   * @param server The server to set
   */
  public void setServer(IPerforceServer server) {
    this.server = server;
  }

  /**
   * Returns the full depot name of the resource.
   * 
   * @return the depot name,
   */
  public abstract String getDepotFilename();

  /**
   * Locates the resource with the given name.
   * 
   * @param name the name of the resource.
   * @param monitor the progress monitor.
   * @return the resource or null.
   * 
   * @throws PerforceException in case of an error.
   */
  public abstract RemoteResource find(String name, IProgressMonitor monitor)
      throws PerforceException;

  public abstract InputStream getContents(IProgressMonitor progress) throws PerforceException;

  public abstract String getName();

  public abstract boolean isContainer();

  public abstract RemoteResource[] members(IProgressMonitor progress) throws PerforceException;

  /**
   * Returns the sync info of the resource.
   * 
   * @param monitor the progress monitor.
   * @return the sync info
   */
  public abstract ResourceSyncInfo getSyncInfo(IProgressMonitor monitor);
}
